package logic

import (
	"fmt"
	"gameserver/gcommon"
	"gameserver/messages"
	"gameserver/tools/TestRobot/cmd"
	"gameserver/tools/TestRobot/internal"
	"gameserver/tools/TestRobot/models"

	"time"

	"gitee.com/night-tc/gobige/common"
	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
)

func init() {
	cmd.GetCmdMgr().RegisterLogic(cmd.Logic_Register, "登录账号,创建角色", (*LogicRegister)(nil))
}

const (
	ReStep_userLogin    StepTypeEnum = iota // 登录账号
	ReStep_GetGroupList                     // 获取服务器列表
	ReStep_CreateRole                       // 创建角色
	RsStep_GameStart                        // 游戏开始
	ReStep_end
)

// 注册逻辑
type LogicRegister struct {
	LogicBase
	token string
}

// 生成命令参数
func (this *LogicRegister) GenCmdParam(cmd *cmd.CmdInfo) {
	//没有参数
	/*
		目前登录的时候，都是拿第1个角色
		后面应该可以改成拿最后一个角色
		这样就可以滚动开新号了。
	*/
}

// 解析命令 成功继续，失败显示命令参数 这里不能设置给this
func (this *LogicRegister) ParseCmd(cmd *cmd.InputCmd) bool {
	//没有参数
	return true
}

// 销毁逻辑
func (this *LogicRegister) Destroy() {
	//http的消息
}

// 类型 名字
func (this *LogicRegister) GetName() string {
	return "LogicRegister"
}

func (this *LogicRegister) Init(user *models.RobotUser) {
	this.LogicBase.Init(user)
	this.LogicBase.realPtr = this
	this.maxStep = ReStep_end
	this.stepLi[ReStep_userLogin] = this.userLogin
	this.stepLi[ReStep_GetGroupList] = this.getGroupList
	this.stepLi[ReStep_CreateRole] = this.createRole
	this.stepLi[RsStep_GameStart] = this.GameStart
}

// 创建账号
func (lg *LogicRegister) userLogin() {
	//先注册用户
	req := messages.LoginByOpenIDReq{
		OpenID:        lg.user.UserName,
		Channel:       lg.user.Channel,
		ClientVersion: global.Version,
	}
	lg.user.ReqStartTime = time.Now().UnixNano()
	url := fmt.Sprintf("%s/%s", internal.Config.Url, "debuglogin")
	if res, err := common.SendHttp[LoginByOpenIDRet](url, req); err != nil {
		logger.Error("LogicRegister.userLogin error:", err)
		lg.SetTimer(10 * time.Second)
		return
	} else if res.Result != gcommon.RETMSG_success {
		logger.Warnf("%s GatewayMsg.userLogin result: %d", lg.user, res.Result)
		return
	} else {
		lg.token = res.Data.Sig
		lg.user.UserID = res.Data.UserID
		lg.SetNext(ReStep_userLogin+1, 0)
	}

}

// 查找指定服务器上是否有角色
func (this *LogicRegister) getGroupList() {

	/*
		pickGroup
		如果有角色，就完成流程
		如果没有角色，就生成角色
	*/
	req := &struct{}{}
	this.user.ReqStartTime = time.Now().UnixNano()
	url := fmt.Sprintf("%s/%s", internal.Config.Url, "loginAfter/getGroupList")
	if res, err := common.SendHttp[GetGroupListRet](url, req, common.SetToken(this.token)); err != nil {
		logger.Error("LogicRegister.getGroupList error:", err)
		this.SetTimer(time.Second * 10)
		return
	} else if res.Result != gcommon.RETMSG_success {
		this.AddErrNum()
		logger.Warnf("LogicRegister.getGroupList result: %d", res.Result)
		return
	} else {
		for _, playerinfo := range res.PlayerList {
			if playerinfo.GroupID == this.user.GroupID {
				this.SetNext(RsStep_GameStart, 0)
				this.user.RolePID = playerinfo.PlayerID
				this.user.RoleName = playerinfo.PlayerName
				return
			}
		}
		this.SetNext(ReStep_CreateRole, 0)
	}
}

// 创建角色
func (this *LogicRegister) createRole() {
	/*
		createRole
		角色生成后，也会有Gateway的地址
	*/
	this.user.ReqStartTime = time.Now().UnixNano()
	req := new(messages.CreatePlayerReq)
	req.GroupID = this.user.GroupID
	req.PlayerName = this.user.RoleName

	url := fmt.Sprintf("%s/%s", internal.Config.Url, "loginAfter/createPlayer")
	if res, err := common.SendHttp[CreatePlayerRet](url, req, common.SetToken(this.token)); err != nil {
		logger.Error("LogicRegister.createRole error:", err)
		this.SetTimer(time.Second * 10)
		return
	} else if res.Result != gcommon.RETMSG_success {
		switch res.Result {
		case gcommon.RETMSG_User_Name_Length:
			this.user.RoleName = internal.GetName()
		case gcommon.RETMSG_User_Name_Repeat:
			charset := []rune(this.user.RoleName)
			key := byte(common.GlobalRand.Rand2(54))
			if key < 26 {
				charset = append(charset, rune(key+65))
			} else {
				charset = append(charset, rune(key-26+97))
			}
			this.user.RoleName = string(charset)
		case gcommon.RETMSG_User_Name_Not_Legal:
			this.user.RoleName = internal.GetName()
		default:
			this.AddErrNum()
			logger.Warnf("LogicRegister.createRole result: %d", res.Result)
		}
		this.SetTimer(time.Second)
		return
	} else {
		this.SetNext(ReStep_CreateRole+1, 0)
		this.user.RolePID = res.Data.PlayerID
		this.user.RoleName = res.Data.PlayerName
		this.SetTimer(time.Second)
	}

}

func (this *LogicRegister) GameStart() {
	this.user.ReqStartTime = time.Now().UnixNano()
	req := new(messages.GameStartByPlayerReq)
	req.PlayerID = this.user.RolePID

	url := fmt.Sprintf("%s/%s", internal.Config.Url, "loginAfter/gameStart")
	if res, err := common.SendHttp[GameStartRet](url, req, common.SetToken(this.token)); err != nil {
		logger.Error("LogicRegister.GameStart error:", err)
		this.SetTimer(time.Second * 10)
		return
	} else if res.Result != gcommon.RETMSG_success {

		this.AddErrNum()
		logger.Warnf("LogicRegister.GameStart result: %d", res.Result)
		return
	} else {
		this.SetNext(RsStep_GameStart+1, 0)
		this.user.GatewayAddr = res.Data.ServerAddr
		this.user.Verify = &protomsg.ClientVerifyReq{
			SessUID:   res.Data.PlayerID,
			SessState: 1,
			SessType:  global.ServerTypeClient,
			Token:     res.Data.Token,
		}
		this.user.RolePID = res.Data.PlayerID
		this.SetTimer(time.Second)
	}
}

type LoginByOpenIDRet struct {
	Result int `json:"result"`
	Data   struct {
		UserID    uint64 `json:"userid"`
		Sig       string `json:"sig"`
		Timestamp uint64 `json:"timestamp"`
		Isadult   bool   `json:"isadult"`
	}
}

type AreaInfo struct {
	*messages.Area_MD
	// 大区下服务器列表
	GroupList []*messages.Group_MD `gorm:"-"`
}

type GetGroupListRet struct {
	Result     int                   `json:"result"`     // 结果码
	ServerList []*AreaInfo           `json:"serverlist"` // 服务器列表
	PlayerList []*messages.Player_MD `json:"playerlist"` // 角色列表
}

type CreatePlayerRet struct {
	Result int                 `json:"result"` // 结果码
	Data   *messages.Player_MD `json:"data"`   // 角色数据
}

type GameStartRet struct {
	Result int `json:"result"` // 结果码
	Data   struct {
		PlayerID   uint64 `json:"playerid"`   // 角色ID
		Token      string `json:"token"`      // 登录Token
		ServerAddr string `json:"serveraddr"` // 服务器地址
	}
}
